///////////////////////////////////////////////////////
// 小车的集装箱有以下的负荷模式:
//      Container1  Container2
// 0:       X           X
// 1:       20          X
// 2:       X           20
// 3:       20          20
// 4:       40 
// 5:       45
////////////////////////////////////////////////////////

export enum AHTCONTAINERMODE {
    MODE0 = 0,
    MODE1 = 1,
    MODE2 = 2,
    MODE3 = 3,
    MODE4 = 4,
    MODE5 = 5,
}

import Icon from 'ol/style/Icon';
import Point from 'ol/geom/Point';
import Polygon from "ol/geom/Polygon.js";
import Style from 'ol/style/Style';
import Feature from 'ol/Feature';
import View from "ol/View";
import VectorSource from 'ol/source/Vector';
import VectorLayer from 'ol/layer/Vector';
import Geometry from "ol/geom/Geometry";
import Fill from "ol/style/Fill";

const SCALE_AHT = 1.0;
const BASE_ZOOM_LEVEL = 10.0;

interface FeatureEx<T extends Geometry> extends Feature<T> {
    updateScale?: () => void,
    update?: () => void,
}

const getScaleFactor = (currentZommLevel: number, baseZoomLevel: number) => Math.pow(2, currentZommLevel - baseZoomLevel);

type PolygonCoordType = [[number, number], [number, number], [number, number], [number, number], [number, number]];
type PolygonsCoordType = PolygonCoordType[];
const calculateContainerCoords = (ahtPosition: [number, number], containerXLength: number, containerYLength: number, mode: AHTCONTAINERMODE): PolygonsCoordType => {
    const centerX = ahtPosition[0];
    const centerY = ahtPosition[1];
    const halfGap = 1000.0;
    const polygons: PolygonsCoordType = [];

    const container1: PolygonCoordType = [
        [centerX - containerXLength / 2, centerY - containerYLength / 2],
        [centerX - containerXLength / 2, centerY - halfGap],
        [centerX + containerXLength / 2, centerY - halfGap],
        [centerX + containerXLength / 2, centerY - containerYLength / 2],
        [centerX - containerXLength / 2, centerY - containerYLength / 2],
    ];
    const container2: PolygonCoordType = [
        [centerX - containerXLength / 2, centerY + halfGap],
        [centerX - containerXLength / 2, centerY + containerYLength / 2],
        [centerX + containerXLength / 2, centerY + containerYLength / 2],
        [centerX + containerXLength / 2, centerY + halfGap],
        [centerX - containerXLength / 2, centerY + halfGap],
    ];
    const container3: PolygonCoordType = [
        [centerX - containerXLength / 2, centerY - containerYLength / 2],
        [centerX - containerXLength / 2, centerY + containerYLength / 2],
        [centerX + containerXLength / 2, centerY + containerYLength / 2],
        [centerX + containerXLength / 2, centerY - containerYLength / 2],
        [centerX - containerXLength / 2, centerY - containerYLength / 2],
    ];

    switch (mode) {
        case AHTCONTAINERMODE.MODE0: {
            break;
        }
        case AHTCONTAINERMODE.MODE1: {
            polygons.push(container1);
            break;
        }
        case AHTCONTAINERMODE.MODE2: {
            polygons.push(container2);
            break;
        }
        case AHTCONTAINERMODE.MODE3: {
            polygons.push(container1);
            polygons.push(container2);
            break;
        }
        case AHTCONTAINERMODE.MODE4: {
            polygons.push(container3);
            break;
        }
        case AHTCONTAINERMODE.MODE5: {
            polygons.push(container3);
            break;
        }
    }
    return polygons;
};

export class AHT {

    // 自身属性
    coordinate: [number, number] = [0.0, 0.0];
    rotation: number = 0.0;
    scale: number = 1.0;
    mode: AHTCONTAINERMODE = AHTCONTAINERMODE.MODE0;

    view!: View;
    layer!: VectorLayer<VectorSource>;
    source!: VectorSource;

    // AHT
    ahtFeature!: FeatureEx<Point>;
    ahtGeometry!: Point;
    ahtIcon!: Icon;
    ahtStyle!: Style;

    // Container
    containerFeature!: FeatureEx<Polygon>;
    containerPolygonGeometry!: Polygon;
    polygonCoords: PolygonsCoordType = [];
    containerStyle: Style;
    containerFill: Fill;

    /**
     * 创建AHT小车, 包含了以下图元: 一个固定了集合锚点的图片Feature
     * @param view 
     * @param layer 
     */
    constructor(view: View, layer: VectorLayer<VectorSource>) {
        this.view = view;
        this.layer = layer;
        this.source = layer.getSource();

        // 初始化
        this.createAht();

        // 更新初始化参数
        this.updateMode();
        this.updateCoordinate();
        this.updateRotation();
        this.updateScale();
    }

    /** 创建AHT的ICON图形, 对象指针 */
    createAht() {
        {
            const geometry = new Point(this.coordinate);
            this.ahtGeometry = geometry;

            const feature = new Feature() as FeatureEx<Point>;
            feature.setGeometry(geometry);
            const icon = new Icon({ src: "/aht.png", anchor: [0.5, 0.5], rotation: 0.0 });
            const style = new Style({ image: icon, zIndex: 0 });
            feature.setStyle(style);
            feature.updateScale = () => {
                const currentZommLevel = this.view.getZoom();
                const scaleRes = this.scale * SCALE_AHT * getScaleFactor(currentZommLevel, BASE_ZOOM_LEVEL);
                icon.setScale(scaleRes);
            }
            this.source.addFeature(feature);

            this.ahtFeature = feature;
            this.ahtIcon = icon;
            this.ahtStyle = style;
        }

        {
            const calculated = calculateContainerCoords(this.coordinate, 2000, 12000, AHTCONTAINERMODE.MODE0);
            const geometry = new Polygon([]);
            geometry.setCoordinates(calculated);
            const feature = new Feature() as FeatureEx<Polygon>;
            const style = new Style({ zIndex: 1 });
            const fill = new Fill({ color: "#47EE1D" });
            style.setFill(fill);
            feature.setStyle(style);

            // 几何处理
            feature.setGeometry(geometry);
            this.source.addFeature(feature);
            feature.update = () => {
                const calculated = calculateContainerCoords(this.coordinate, 2000, 12000, this.mode);
                geometry.setCoordinates(calculated);
                geometry.rotate(-this.rotation, this.coordinate);
            }

            this.containerFeature = feature;
            this.containerPolygonGeometry = geometry;
            this.containerStyle = style;
            this.containerFill = fill;
        }
    }

    /** 更新当前运载负荷 */
    updateMode() {
        this.containerFeature.update();
    }

    /** 更新缩放 */
    updateScale() {
        this.ahtFeature.updateScale();
    }

    /** 更新坐标 */
    updateCoordinate() {
        this.ahtGeometry.setCoordinates(this.coordinate);
        this.containerFeature.update();
    }

    /** 更新旋转 */
    updateRotation() {
        this.ahtIcon.setRotation(this.rotation);
        this.containerFeature.update();
    }

    setMode(modeI = 0) {
        this.mode = modeI;
        this.updateMode();
    }

    setSacle(scaleI = 1.0) {
        this.scale = scaleI;
        this.ahtFeature.updateScale();
    }

    setCoordinate(coordinateI = [0.0, 0.0]) {
        this.coordinate[0] = coordinateI[0];
        this.coordinate[1] = coordinateI[1];
        this.updateCoordinate();
    }

    setRotation(rotationI = 0.0) {
        this.rotation = rotationI;
        this.updateRotation();
    }
}